package com.efamily.ewallet.server;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;

import com.efamily.ewallet.client.account.bean.AccountBean;
import com.efamily.ewallet.client.expense.bean.ExpenseBean;
import com.efamily.ewallet.client.expense.bean.ExpenseCategoryBean;
import com.efamily.ewallet.client.expense.bean.ExpenseSearchConfig;
import com.efamily.ewallet.client.expense.bean.ExpenseTypeBean;
import com.efamily.ewallet.client.expense.service.ExpenseService;
import com.extjs.gxt.ui.client.data.BasePagingLoadResult;
import com.extjs.gxt.ui.client.data.PagingLoadConfig;
import com.extjs.gxt.ui.client.data.PagingLoadResult;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;

/**
 * The server side implementation of the RPC service.
 */
@SuppressWarnings("serial")
public class ExpenseServiceImpl extends RemoteServiceServlet implements
		ExpenseService {

	public PagingLoadResult<ExpenseBean> getExpenses(AccountBean accountBean, 
			ExpenseSearchConfig searchConfig, PagingLoadConfig config) {
		System.out.println("Load Expense");
		List<ExpenseBean> beans = loadExpensesBeans();
		if (config.getSortInfo().getSortField() != null) {
			final String sortField = config.getSortInfo().getSortField();
			if (sortField != null) {
				Collections.sort(beans, config.getSortInfo().getSortDir()
						.comparator(new Comparator<ExpenseBean>() {
							@SuppressWarnings("deprecation")
							public int compare(ExpenseBean o1, ExpenseBean o2) {
								if (sortField.equals("id")) {
									return o1.getId() < o2.getId() ? -1 : (o1
											.getId() == o2.getId()) ? 0 : 1;
								} else if (sortField.equals("name")) {
									return o1.getName().compareTo(o2.getName());
								} else if (sortField.equals("category")) {
									return o1.getCategory().getName()
											.compareTo(
													o2.getCategory().getName());
								} else if (sortField.equals("type")) {
									return o1.getType().getName().compareTo(
											o2.getType().getName());
								} else if (sortField.equals("expense_date")) {
									return o1.getExpenseDate().compareTo(
											o2.getExpenseDate());
								} else if (sortField.equals("week_day")) {
									return o1.getExpenseDate().getDay() < o2
											.getExpenseDate().getDay() ? -1
											: (o1.getExpenseDate().getDay() == o2
													.getExpenseDate().getDay()) ? 0
													: 1;
								} else if (sortField.equals("month_day")) {
									return o1.getExpenseDate().getDate() < o2
											.getExpenseDate().getDate() ? -1
											: (o1.getExpenseDate().getDate() == o2
													.getExpenseDate().getDate()) ? 0
													: 1;
								} else if (sortField.equals("month")) {
									return o1.getExpenseDate().getMonth() < o2
											.getExpenseDate().getMonth() ? -1
											: (o1.getExpenseDate().getMonth() == o2
													.getExpenseDate()
													.getMonth()) ? 0 : 1;
								} else if (sortField.equals("year")) {
									int o1Year = o1.getExpenseDate().getYear() + 1900;
									int o2Year = o2.getExpenseDate().getYear() + 1900;
									return o1Year < o2Year ? -1
											: (o1Year == o2Year) ? 0 : 1;
								} else if (sortField.equals("cost")) {
									return o1.getCost() < o2.getCost() ? -1
											: (o1.getCost() == o2.getCost()) ? 0
													: 1;
								}
								return 0;
							}
						}));
			}
		}

		List<ExpenseBean> sublist = new ArrayList<ExpenseBean>();
		int start = config.getOffset();
		int limit = beans.size();
		if (config.getLimit() > 0) {
			limit = Math.min(start + config.getLimit(), limit);
		}
		for (int i = config.getOffset(); i < limit; i++) {
			sublist.add(beans.get(i));
		}
		return new BasePagingLoadResult<ExpenseBean>(sublist, config
				.getOffset(), beans.size());

	}
	
	public List<ExpenseCategoryBean> getCategories(AccountBean accountBean){
		List<ExpenseCategoryBean> categories = loadCategoryBean();
		return categories;
	}

	private List<ExpenseBean> loadExpensesBeans() {
		List<ExpenseBean> beans = new ArrayList<ExpenseBean>();
		List<ExpenseTypeBean> types1 = new ArrayList<ExpenseTypeBean>();
		types1.add(new ExpenseTypeBean(1, "food"));
		types1.add(new ExpenseTypeBean(2, "clothes"));
		types1.add(new ExpenseTypeBean(3, "footwear"));
		ExpenseCategoryBean category1 = new ExpenseCategoryBean(1, "purchase", types1);
		ExpenseBean bean1 = new ExpenseBean(1, "bean1", category1, new ExpenseTypeBean(2, "clothes"), new Date(),
				100, "first credit");
		beans.add(bean1);
		List<ExpenseTypeBean> types2 = new ArrayList<ExpenseTypeBean>();
		types2.add(new ExpenseTypeBean(4, "deposit"));
		types2.add(new ExpenseTypeBean(5, "investment"));
		ExpenseCategoryBean category2 = new ExpenseCategoryBean(2, "accumulation", types2);
		ExpenseBean bean2 = new ExpenseBean(7, "bean2", category2, new ExpenseTypeBean(5, "investment"), new Date(),
				100, "first credit");
		beans.add(bean2);
		ExpenseBean bean3 = new ExpenseBean(5, "bean3", category1, new ExpenseTypeBean(3, "footwear"), new Date(),
				100, "second purchases");
		beans.add(bean3);

		return beans;
	}
	
	private List<ExpenseCategoryBean> loadCategoryBean(){
		List<ExpenseCategoryBean> categories = new ArrayList<ExpenseCategoryBean>();
		List<ExpenseTypeBean> types1 = new ArrayList<ExpenseTypeBean>();
		types1.add(new ExpenseTypeBean(1, "food"));
		types1.add(new ExpenseTypeBean(2, "clothes"));
		types1.add(new ExpenseTypeBean(3, "footwear"));
		ExpenseCategoryBean category1 = new ExpenseCategoryBean(1, "purchase", types1);
		List<ExpenseTypeBean> types2 = new ArrayList<ExpenseTypeBean>();
		types2.add(new ExpenseTypeBean(4, "deposit"));
		types2.add(new ExpenseTypeBean(5, "investment"));
		ExpenseCategoryBean category2 = new ExpenseCategoryBean(2, "accumulation", types2);
		List<ExpenseTypeBean> types3 = new ArrayList<ExpenseTypeBean>();
		types3.add(new ExpenseTypeBean(6, "resort"));
		types3.add(new ExpenseTypeBean(7, "disco"));
		types3.add(new ExpenseTypeBean(8, "football"));
		ExpenseCategoryBean category3 = new ExpenseCategoryBean(3, "relaxation", types3);
		ExpenseCategoryBean category4 = new ExpenseCategoryBean(4, "loss", null);
		categories.add(category1);
		categories.add(category2);
		categories.add(category3);
		categories.add(category4);
		return categories;
	}

	public boolean addEditExpense(AccountBean accountBean, ExpenseBean expense) {
		/*if(expense.getId()==-1){
			//TODO save new expense
		}else{
			ExpenseCategoryBean categoryBean = expense.getCategory();
			if(categoryBean.getId()==-1){
				categoryBean.getTypes().add(expense.getType());
				//TODO save new category 
				int id = 1;//TODO get id
				categoryBean.setId(id);
				
			}
			//TODO update expense
		}*/
		
		return true;
	}
	public boolean deleteExpenses(AccountBean accountBean, List<Integer> expensesID){
		return true;
	}
}
